/**
 * 获取当前可视屏幕的宽高，生成一个和可视屏幕相同宽高的canvas
 */
let ctx = null
let width = 0
let height = 0
const canvasId = 'canvas-snow'
const snows = []
const snowIcon = require('@/assets/images/snow.svg')
function createCanvas () {
  const doc = document.documentElement
  width = doc.clientWidth
  height = doc.clientHeight
  const canvas = document.createElement('canvas')
  canvas.id = canvasId
  canvas.width = width
  canvas.height = height
  const styleMap = {
    zIndex: 9999999,
    pointerEvents: 'none',
    position: 'fixed',
    left: 0,
    top: 0
  }
  for (const k in styleMap) {
    canvas.style[k] = styleMap[k]
  }
  document.querySelector('body').appendChild(canvas)
  ctx = canvas.getContext('2d')
  ctx.fillStyle = 'transparent'
  ctx.fillRect(0, 0, width, height)
  ctx.globalAlpha = 0.5
}

/**
 *
 * @param { size, x, y ... } options
 */
function Snow ({ x, y, size, ...options }) {
  this.options = options
  this.img = null
  this.size = size
  this.x = x
  this.y = y
  this.vy = Math.pow(this.size, 0.36)
  this.vx = getRandomNum(-2, 2)

  /**
   * 绘制单个雪花
   */
  this.drawSnow = function () {
    return new Promise((resolve, reject) => {
      const img = new Image()
      img.src = snowIcon
      img.onload = () => {
        ctx.drawImage(img, this.x, this.y, this.size, this.size)
        ctx.beginPath()
        this.img = img
        resolve()
      }
    })
  }

  this.snowMove = function () {
    this.y += this.vy
    this.x += this.vx
    ctx.drawImage(this.img, this.x, this.y, this.size, this.size)
  }
}

async function snowCanvasDown () {
  if (document.querySelector(`#${canvasId}`)) {
    return
  }
  createCanvas()
  for (let i = 0; i < 100; i++) {
    const snowOptions = {
      x: getRandomNum(100, width - 100),
      y: getRandomNum(-260, 30),
      size: getRandomNum(6, 36)
    }
    const snow = new Snow(snowOptions)
    await snow.drawSnow()
    snows.push(snow)
  }

  function requestAnimation () {
    ctx.clearRect(0, 0, width, height)
    ctx.fillStyle = 'transparent'
    ctx.fillRect(0, 0, width, height)
    for (let i = 0; i < snows.length; i++) {
      snows[i].snowMove()
    }
    if (snows.some((o) => o.y < height)) {
      window.requestAnimationFrame(requestAnimation)
    } else {
      ctx = null
      width = 0
      height = 0
      snows.length = 0
      document.querySelector(`#${canvasId}`).remove()
    }
  }

  requestAnimation()
}

/**
 * 根据起点和终点获取中间任意值
 * @param { number } min 区间最小值
 * @param { number } max 区间最大值
 * @return { number }
 */
function getRandomNum (min, max) {
  const t = Math.random() * (max - min) + min
  return t
}

export default snowCanvasDown
